<template>
	<view class="main">
		<view v-show="isConnected">
			<view class="item">
				<u-input v-model="message.ssid" placeholder="Wi-Fi名称"></u-input>
			</view>
			<view class="item">
				<u-input v-model="message.password" placeholder="Wi-Fi密码"></u-input>
			</view>
			<view class="item">
				<u-button type="warning" :loading="messageSend" @click="writeBLECharacteristicValue()">发送</u-button>
			</view>
			<view class="item">
				<u-button type="error" :loading="messageSend" @click="closeBLEConnection()">断开设备</u-button>
			</view>
		</view>
		
		<view v-show="!isConnected">
			<u-cell-group class="item">
				<view v-for="device in bluetoothDevices">
					<u-cell :title="device.name">
						<view slot="value">
							<view>
								<u-button type="primary" style="width: 40px;" @click="connect(device.deviceId)" :loading="connectng">连接</u-button>
							</view>
						</view>
					</u-cell>
				</view>
			</u-cell-group>
		</view>
	</view>
</template>
<script>
	export default {
		data() {
			return {
				bluetoothDevices: [],
				deviceId: '',
				serviceId: '',
				characteristics: [],
				message: {
					ssid: '',
					password: ''
				},
				isConnected: false,
				messageSend: false
			}
		},
		methods: {
			test() {
				var msg = JSON.stringify(this.message)
				console.log(msg)
			},
			//打开蓝牙适配器
			openBluetoothAdapter() {
				let _this = this
				uni.openBluetoothAdapter({
					success(res) {
						uni.getBluetoothAdapterState({
							success() {
								console.log('本机设备的蓝牙已打开')
								// 开始搜索蓝牙设备
								_this.startBluetoothDeviceDiscovery()
							},
							fail() {
								console.log('查看手机蓝牙是否打开')
							}
						})
					},
					fail() {
						console.log('查看手机蓝牙是否打开')
					}
				})
			},
			//搜索蓝牙设备
			startBluetoothDeviceDiscovery() {
				let _this = this
				uni.startBluetoothDevicesDiscovery({
					success(res) {
						// 发现外围设备
						console.log("开始搜索")
						_this.onBluetoothDeviceFound()
					},
					fail(err) {
						console.log(err, '错误信息')
					}
				})
			},
			//搜索到蓝牙设备
			onBluetoothDeviceFound() {
				let _this = this
				uni.onBluetoothDeviceFound(function(devices) {
					if (devices.devices[0].name != "") {
						if (_this.bluetoothDevices.indexOf(devices.devices[0].deviceId == -1)) {
							console.log(devices.devices[0].name)
							_this.bluetoothDevices.push({deviceId: devices.devices[0].deviceId,name: devices.devices[0].name})
						}
					}
				})
			},
			connect(deviceId) {
				let _this = this
				//连接蓝牙
				uni.createBLEConnection({
					// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
					deviceId: deviceId,
					success(res) {
						_this.stopBluetoothDevicesDiscovery()
						console.log("蓝牙连接成功")
						_this.deviceId = deviceId
						_this.isConnected = true
						_this.getBLEDeviceServices()
						uni.showModal({
							title: '提示',
							content: '连接成功',
							showCancel: false
						})
					},
					fail(err) {
						console.log("蓝牙连接失败")
					}
				})
			},
			//停止搜寻蓝牙设备
			stopBluetoothDevicesDiscovery() {
				uni.stopBluetoothDevicesDiscovery({
					success(res) {
						console.log('停止搜索蓝牙设备');
					},
					fail(err) {
						console.log('停止搜索蓝牙设备失败')
					}
				});
			},
			//获取蓝牙的所有服务
			getBLEDeviceServices() {
				let _this = this
				setTimeout(() => {
					uni.getBLEDeviceServices({
						deviceId: _this.deviceId,
						success(res) {
							console.log(res)
							_this.serviceId = res.services[0].uuid
							_this.getBLEDeviceCharacteristics()
						},
						fail(err) {
							console.log(err)
						}
					})
				},2000)
			},
			//获取蓝牙特征
			getBLEDeviceCharacteristics() {
				let _this = this
				uni.getBLEDeviceCharacteristics({
					deviceId: _this.deviceId,
					serviceId: _this.serviceId,
					success(res) {
						console.log(res)
						_this.characteristics = res.characteristics
						_this.notifyBLECharacteristicValueChange()
					},
					fail(err) {
						console.log(err)
					}
				})
			},
			//启用 notify 功能
			notifyBLECharacteristicValueChange() {
				let _this = this
				uni.notifyBLECharacteristicValueChange({
					state: true,
					deviceId: _this.deviceId,
					serviceId: _this.serviceId,
					characteristicId: _this.characteristics[0].uuid,
					success(res) {
						uni.onBLECharacteristicValueChange(function (res) {
							var text = _this.arrayBufferToStr(res.value)
							console.log(res)
							console.log(text)
							if (text == 1) {
								uni.showModal({
									title: '提示',
									content: '联网成功',
									showCancel: false,
									success: function(res) {
										if (res.confirm) {
											uni.navigateBack()
										}
									}
								})
							}
						})
					},
					fail(err) {
						console.log(err)
					}
				})
			},
			//写入数据
			writeBLECharacteristicValue() {
				let _this = this
				var msg = JSON.stringify(_this.message)
				var binary = _this.strToArrayBuffer(msg)
				uni.writeBLECharacteristicValue({
					deviceId: _this.deviceId,
					serviceId: _this.serviceId,
					characteristicId: _this.characteristics[1].uuid,
					value: binary,
					success(res) {
						console.log(res)
						_this.messageSend = true
					},
					fail(err) {
						console.log(err)
					}
				})
			},
			//断开蓝牙连接
			closeBLEConnection() {
				let _this = this
				uni.closeBLEConnection({
					deviceId: _this.deviceId,
					success(res) {
						console.log(res)
						console.log('断开成功')
						_this.isConnected = false
						_this.bluetoothDevices = []
						_this.openBluetoothAdapter()
					},
					fail(err) {
						console.log(err)
						console.log('断开失败')
					}
				})
			},
			//字符串转ArrayBuffer
			strToArrayBuffer(str) {
			    var array = new Uint8Array(str.length);
			    for(var i = 0; i < str.length; i++) {
			        array[i] = str.charCodeAt(i);
			    }
			    return array.buffer
			},
			//ArrayBuffer转字符串
			arrayBufferToStr(abf) {
				return String.fromCharCode.apply(null, new Uint8Array(abf))
			}
		},
		onLoad() {
			this.openBluetoothAdapter()
		},
		onUnload() {
			uni.closeBluetoothAdapter({
				success(res) {
					console.log('卸载蓝牙成功')
				},
				fail(err) {
					console.log('卸载蓝牙失败')
				}
			})
		}
	}
</script>

<style>
	.main {
		margin: 0 10px 10px 10px;
	}

	.item {
		margin-top: 10px;
	}
</style>